package com.fin.zw.aiqas.util;

import org.jaudiotagger.audio.AudioFileIO;
import org.jaudiotagger.audio.mp3.MP3AudioHeader;
import org.jaudiotagger.audio.mp3.MP3File;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class AudioUtile {




    /**
     * 获取语音文件播放时长(秒) 支持wav 格式
     *
     * @param file
     * @return
     */
    public static Float getDuration(File file) {
        try {
            AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(file);
            AudioFormat format = audioInputStream.getFormat();
            long audioFileLength = file.length();
            int frameSize = format.getFrameSize();
            float frameRate = format.getFrameRate();
            float durationInSeconds = (audioFileLength / (frameSize * frameRate));
            return durationInSeconds;

        } catch (Exception e) {
            e.printStackTrace();
            return 1f;
        }

    }


    public static int toInt(byte[] b) {
        return ((b[3] << 24) + (b[2] << 16) + (b[1] << 8) + (b[0] << 0));
    }

    public static short toShort(byte[] b) {
        return (short)((b[1] << 8) + (b[0] << 0));
    }

    public static byte[] read(RandomAccessFile rdf, int pos, int length) throws IOException {
        rdf.seek(pos);
        byte result[] = new byte[length];
        for (int i = 0; i < length; i++) {
            result[i] = rdf.readByte();
        }
        return result;
    }

    public static Map<String, Object> getWavInfo(File file) throws IOException{
        Map<String, Object> audioInfo = new HashMap<String,Object>();

        // fmt 得格式代码 前5项编码均为pcm格式
        //        格式代码	格式名称	fmt 块长度	fact 块
        //        1(0x0001)	PCM/非压缩格式	16
        //        2(0x0002	Microsoft ADPCM	18	√
        //        3(0x0003)	IEEE float	18	√
        //        6(0x0006)	ITU G.711 a-law	18	√
        //        7(0x0007)	ITU G.711 μ-law	18	√
        //        49(0x0031)	GSM 6.10	20	√
        //        64(0x0040)	ITU G.721 ADPCM		√
        //        65,534(0xFFFE)	见子格式块中的编码格式	40

        RandomAccessFile rdf = new RandomAccessFile(file,"r");
        int fileSize = toInt(read(rdf,4,4));                //文件大小
        short fmt = toShort(read(rdf, 20,2));               //编码格式
        short channels = toShort(read(rdf,22,2));           //通道数
        int sampleRate = toInt(read(rdf,24,4));             //采样率
        int codeRate = toInt(read(rdf, 28, 4));             //码率 即播放速度  bps
        short frameSize = toShort(read(rdf, 32, 2));        //帧大小 btye/ frame
        short bits = toShort(read(rdf, 34,2));              //采样位数
        rdf.close();
        audioInfo.put("fmt",fmt);
        audioInfo.put("size", file);
        audioInfo.put("channels",channels);
        audioInfo.put("sampleRate", sampleRate);
        audioInfo.put("codeRate", codeRate);
        audioInfo.put("frameSize", frameSize);
        audioInfo.put("bits", bits);
        audioInfo.put("duration", codeRate==0 ? 0 : fileSize*1.0/codeRate);
        return audioInfo;
    }


    public static String ChangeWavCodec(File file){
        ProcessBuilder proscessBuilder = new ProcessBuilder();
        String filePath = file.getPath();
        String fileName = file.getName();
        List<String> cmd = new ArrayList<>();
        try {
            String newPath = filePath.replace(fileName, "codec_"+fileName);
            //String cmd = String.format("ffmpeg -i %s -f wav %s", filePath, newPath);
            cmd.add("/usr/local/ffmpeg/bin/ffmpeg");
            cmd.add("-i");
            cmd.add(filePath);
            cmd.add("-f");
            cmd.add("wav");
            cmd.add(newPath);
            proscessBuilder.command(cmd);
            proscessBuilder.redirectErrorStream(true);
            proscessBuilder.start().waitFor();
            return newPath;
        }catch (IOException ioex){
            ioex.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return fileName;
    }

    /**
     * 获取mp3语音文件播放时长(秒) mp3
     *
     * @param file
     * @return
     */
    public static Map<String, Object> getMp3Info(File file) {
        Map<String, Object> audioInfo = new HashMap<String,Object>();
        audioInfo.put("fmt", (short) 0);
        try {
            MP3File f = (MP3File) AudioFileIO.read(file);
            MP3AudioHeader audioHeader = (MP3AudioHeader) f.getAudioHeader();
//            Float duration =  Float.parseFloat(audioHeader.getTrackLength() + "");
            Double duration = Double.valueOf(audioHeader.getTrackLength());
            audioInfo.put("duration",duration);
        } catch (Exception e) {
            e.printStackTrace();
            audioInfo.put("duration", 0);
        }
        return audioInfo;
    }


}
